/*****************************************************************************
 Analizador lexico para el trabajo practico
******************************************************************************/

%option noyywrap nodefault yylineno

%{
#include "traductor.h"

void descartar_comentario(void);

%}

digito          [0-9]
letra           [A-Za-z]
identificador   {letra}({letra}|{digito}|_)*
caracter        "'"(.|\n)+"'"
entero          (-)?{digito}+ 
real            (-)?{digito}+"."{digito}+
espacios        [ \t]+
%%

"\""(.)*"\""            { yylval.lexema=strdup(yytext); return(LITERAL); };    
"/*"                    { descartar_comentario(); }
#{letra}*               {  }
"<"({letra}|.|_)*">"    {  }
{espacios}              { ; }
\n                      { ; }    
"int"                   { return(INTEGER); }
"char"                  { return(CHAR); }
"float"                 { return(FLOAT); }
"void"                  { return(VOID); }
"if"                    { return(IF); }
"else"                  { return(ELSE); }
"for"                   { return(FOR); }
"while"                 { return(WHILE); }
"do"                    { return(DO); }
"return"                { return(RETURN); }
"{"                     { return('{'); }
"}"                     { return('}'); }
"("                     { return('('); }
")"                     { return(')'); }
"["                     { return('['); }
"]"                     { return(']'); }
"&&"                    { return(AND); }
"||"                    { return(OR); }
"!"                     { return('!'); }
"=="                    { return(EQUALEQUAL); }
"--"                    { return(MINUSMINUS); }
"++"                    { return(PLUSPLUS); }
"+="                    { return(PLUSEQUAL); }
"*="                    { return(MULEQUAL); }
"/="                    { return(DIVEQUAL); }
"-="                    { return(MINUSEQUAL); }
"+"                     { return('+'); }
"-"                     { return('-'); }
"%"                     { return('%'); }    
"/"                     { return('/'); }
"*"                     { return('*'); }
"!="                    { return(DISCTINCT); }
"<="                    { return(MINEQUAL); }    
">="                    { return(MAYEQUAL); }
"<"                     { return('<'); }        
">"                     { return('>'); }        
"="                     { return('='); }
";"                     { return(';'); }
","                     { return(','); }
"printf"                { return(PRINTF); }
{identificador}         { 
                            yylval.lexema=strdup(yytext);
                            return(ID);     
                        }
{caracter}              {
                            yylval.lexema=strdup(yytext);
                            return(CARACTER); 
                        }
{entero}                {
                            yylval.lexema=strdup(yytext);
                            return(ENTERO); 
                        }
{real}                  { 
                            yylval.lexema=strdup(yytext);
                            return(REAL); }
.                       {   printf("Error lexico: linea %d: %c no es un caracter valido\n", yylineno, *yytext); }    

"//".*                  /* No hacer nada para los comentarios de una linea */


%%

void
descartar_comentario()
{
    char c, prev = 0;

    while ((c = input()) != EOF) {
		if (c == '/' && prev == '*')
			return;
		prev = c;
	}
	printf("%s%d\n", "error lexico, comentario abierto en linea %d.", yylineno);
}

int
cambiar_yyin(FILE *archivo)
{
    yyrestart(archivo);
    return EXITO_ABRIR_ARCHIVO;
}

